package com.relytosoft.mizar.media.analyze.services.controller.behavior;

import cn.dev33.satoken.annotation.SaCheckPermission;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.relytosoft.dubhe.common.core.base.page.PageQuery;
import com.relytosoft.dubhe.common.core.exception.ServiceException;
import com.relytosoft.dubhe.common.core.object.ResponseResult;
import com.relytosoft.dubhe.common.core.utils.BeanCopyUtils;
import com.relytosoft.dubhe.common.core.utils.CommonUtils;
import com.relytosoft.dubhe.common.log.annotation.OpLog;
import com.relytosoft.dubhe.common.log.enums.OpTypeEnum;
import com.relytosoft.mizar.media.analyze.api.entity.behavior.AyBehaviorTask;
import com.relytosoft.mizar.media.analyze.api.entity.behavior.AyBehaviorTaskSon;
import com.relytosoft.mizar.media.analyze.api.pojo.dto.AyBehaviorTaskDto;
import com.relytosoft.mizar.media.analyze.api.pojo.dto.AyBehaviorUpdateDto;
import com.relytosoft.mizar.media.analyze.api.pojo.query.AyBehaviorTaskQuery;
import com.relytosoft.mizar.media.analyze.api.pojo.vo.AyBatchVo;
import com.relytosoft.mizar.media.analyze.api.pojo.vo.AyBehaviorTaskVo;
import com.relytosoft.mizar.media.analyze.api.pojo.vo.AyEventTypeVo;
import com.relytosoft.mizar.media.analyze.services.service.behavior.AyBehaviorTaskService;
import com.relytosoft.mizar.media.analyze.services.service.behavior.AyBehaviorTaskSonService;
import com.relytosoft.mizar.media.common.enums.TaskStatusEnum;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.simpleframework.xml.core.Validate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author lj
 * @date 2022/6/7 10:28
 */
@Api(tags = "行为分析任务")
@RestController
@RequestMapping("/analyze/behavior")
public class AyBehaviorTaskController {

    @Resource
    private AyBehaviorTaskService ayBehaviorTaskService;

    @Resource
    private AyBehaviorTaskSonService ayBehaviorTaskSonService;


    @SaCheckPermission("analyze:behavior:list")
    @OpLog(msg = "查询行为分析主任务", opType = OpTypeEnum.SELECT)
    @ApiOperation("分页条件查询行为分析任务")
    @GetMapping("/list")
    public ResponseResult<Map<String, Object>> list(AyBehaviorTaskQuery ayBehaviorTaskQuery, PageQuery pageQuery) {
        Page<AyBehaviorTaskVo> page = ayBehaviorTaskService.selectAyBehaviorTaskPageList(pageQuery, ayBehaviorTaskQuery);
        return ResponseResult.ok(CommonUtils.getPageData(page));
    }


    @SaCheckPermission("analyze:behavior:add")
    @OpLog(msg = "创建行为分析任务", opType = OpTypeEnum.INSERT)
    @ApiOperation("创建行为分析任务")
    @PostMapping("/batch/add")
    public ResponseResult<AyBatchVo> insert(@Validate @RequestBody AyBehaviorTaskDto ayBehaviorTaskDto) {
        //判断ayBehaviorTaskDto中状态值和TaskStatusEnum.NOT_STARTED和TaskStatusEnum.CREATED是否相等，如果都不相等则抛出异常
        if (!Objects.equals(ayBehaviorTaskDto.getStatus(), TaskStatusEnum.NOT_STARTED.getValue()) &&
                !Objects.equals(ayBehaviorTaskDto.getStatus(), TaskStatusEnum.CREATED.getValue())) {
            throw new ServiceException("任务状态只能为启动或不启动！");
        }
        //返回结果
        AyBatchVo ayBatchVo = new AyBatchVo();
        ayBatchVo.setTotal(ayBehaviorTaskDto.getAyCameraVos().size());
        //获取AyBehaviorTask对象
        AyBehaviorTask ayBehaviorTask = ayBehaviorTaskService.getAyBehaviorTask(ayBehaviorTaskDto);
        //获取AyBehaviorTaskSon对象
        List<AyBehaviorTaskSon> ayBehaviorTaskSonList = ayBehaviorTaskService.getAyBehaviorTaskSon(ayBehaviorTask);
        //保存AyBehaviorTask和AyBehaviorTaskSon
        boolean flag = ayBehaviorTaskService.saveAyBehaviorTaskAndSon(ayBehaviorTask, ayBehaviorTaskSonList, ayBatchVo);
        if (flag) {
            if (ayBehaviorTaskDto.getStatus().equals(TaskStatusEnum.CREATED.getValue())) {
                for (AyBehaviorTaskSon ayBehaviorTaskSon : ayBehaviorTaskSonList) {
                    ayBehaviorTaskSonService.sendMessage(ayBehaviorTaskSon);
                }
            }
        }
        return ResponseResult.ok(ayBatchVo);
    }


    @SaCheckPermission("analyze:behavior:update")
    @OpLog(msg = "修改行为分析任务", opType = OpTypeEnum.UPDATE)
    @ApiOperation("修改行为分析任务")
    @PutMapping({"/update"})
    public ResponseResult<Void> update(@RequestBody AyBehaviorUpdateDto ayBehaviorUpdateDto) {
        //根据id查询AyBehaviorTask对象
        AyBehaviorTask ayBehaviorTask = ayBehaviorTaskService.getById(ayBehaviorUpdateDto.getId());
        //任务为空，或任务状态不为未启动、已结束时，不允许修改
        if (!Objects.equals(ayBehaviorTask.getStatus(), TaskStatusEnum.NOT_STARTED.getValue()) &&
                !Objects.equals(ayBehaviorTask.getStatus(), TaskStatusEnum.FINISHED.getValue())) {
            throw new ServiceException("任务不允许修改");
        }
        //获取AyBehaviorTask对象
        AyBehaviorTask updateAyBehaviorTask = BeanCopyUtils.copy(ayBehaviorUpdateDto, AyBehaviorTask.class);
        boolean update = ayBehaviorTaskService.updateById(updateAyBehaviorTask);
        //TODO 是否需要修改子任务名称？
        if (update) {
            return ResponseResult.ok("修改成功");
        }
        return ResponseResult.fail("修改失败");
    }

    @SaCheckPermission("analyze:behavior:delete")
    @OpLog(msg = "删除行为分析任务", opType = OpTypeEnum.DELETE)
    @ApiOperation("删除行为分析任务")
    @PutMapping({"/delete"})
    public ResponseResult<Void> delete(@RequestBody List<Integer> ids) {
        //对需要删除的任务和子任务进行校验
        List<AyBehaviorTask> ayBehaviorTaskList = ayBehaviorTaskService.checkDelete(ids);
        //为空，则说明没有需要删除的任务和子任务
        if (ayBehaviorTaskList.isEmpty()) {
            return ResponseResult.fail("没有符合条件的任务需要删除");
        }
        //删除任务和子任务
        boolean delete = ayBehaviorTaskService.deleteAyBehaviorTask(ids, ayBehaviorTaskList);
        if (delete) {
            return ResponseResult.ok("删除符合条件的数据成功");
        } else {
            return ResponseResult.fail("删除符合条件的数据失败");
        }
    }

    @SaCheckPermission("analyze:behavior:start")
    @OpLog(msg = "启动行为分析任务", opType = OpTypeEnum.OTHER)
    @ApiOperation("启动行为分析任务")
    @PostMapping({"/start"})
    public ResponseResult<AyBatchVo> start(@RequestBody List<Integer> ids) {
        //校验是否有需要启动的任务
        AyBatchVo ayBatchVo = ayBehaviorTaskService.checkStart(ids);
        //如果ayBatchVo的total和Error数相等，则说明没有需要启动的任务
        if (ayBatchVo.getTotal().equals(ayBatchVo.getError())) {
            return ResponseResult.fail(ayBatchVo);
        }
        //获取可以启动的子任务
        List<AyBehaviorTaskSon> ayBehaviorTaskSonList = ayBehaviorTaskService.selectCanStartSonTask(ids);
        //判断ayBehaviorTaskSonList是否为空
        if (ayBehaviorTaskSonList.isEmpty()) {
            return ResponseResult.fail(ayBatchVo);
        }
        //启动任务
        //获取已结束，未删除的子任务并封装为需要添加的子任务集合
        List<AyBehaviorTaskSon> insertTaskSons = new ArrayList<>();
        //获取异常、未启动、未删除的子任务
        List<AyBehaviorTaskSon> startTaskSons = new ArrayList<>();
        ayBehaviorTaskService.startTask(ayBehaviorTaskSonList, ayBatchVo, insertTaskSons, startTaskSons);
        //判断insertTaskSons不为空，发送消息到消息队列
        if (!insertTaskSons.isEmpty()) {
            //发送消息到消息队列
            insertTaskSons.forEach(ayBehaviorTaskSon -> ayBehaviorTaskSonService.sendMessage(ayBehaviorTaskSon));
        }
        //判断startTaskSons不为空，发送消息到消息队列
        if (!startTaskSons.isEmpty()) {
            //发送消息到消息队列
            startTaskSons.forEach(ayBehaviorTaskSon -> ayBehaviorTaskSonService.sendMessage(ayBehaviorTaskSon));
        }
        return ResponseResult.ok(ayBatchVo);
    }

    @SaCheckPermission("analyze:behavior:stop")
    @OpLog(msg = "停止行为分析任务", opType = OpTypeEnum.OTHER)
    @ApiOperation("停止行为分析任务")
    @PostMapping({"/stop"})
    public ResponseResult<AyBatchVo> stop(@RequestBody List<Integer> ids) {
        //校验是否有需要停止的任务
        AyBatchVo ayBatchVo = ayBehaviorTaskService.checkStop(ids);
        // 如果ayBatchVo的total和Error数相等，则说明没有需要停止的任务
        if (ayBatchVo.getTotal().equals(ayBatchVo.getError())) {
            return ResponseResult.fail(ayBatchVo);
        }
        //获取可以停止的子任务
        List<AyBehaviorTaskSon> ayBehaviorTaskSonList = ayBehaviorTaskService.selectCanStopSonTask(ids);
        //判断ayBehaviorTaskSonList是否为空
        if (ayBehaviorTaskSonList.isEmpty()) {
            return ResponseResult.fail(ayBatchVo);
        }
        //停止任务
        List<AyBehaviorTaskSon> stopTaskSons = new ArrayList<>();
        ayBehaviorTaskService.stopTask(ayBehaviorTaskSonList, ayBatchVo, stopTaskSons);
        //判断stopTaskSons不为空，发送消息到消息队列
        if (!stopTaskSons.isEmpty()) {
            //遍历stopTaskSons，发送消息
            for (AyBehaviorTaskSon ayBehaviorTaskSon : stopTaskSons) {
                //TODO 发送消息到消息队列
                ayBehaviorTaskSonService.sendDeleteMessage(ayBehaviorTaskSon);
            }
        }
        return ResponseResult.ok(ayBatchVo);
    }

    @OpLog(msg = "查询行为分析任务列表", opType = OpTypeEnum.SELECT)
    @ApiOperation("查询行为分析任务列表")
    @GetMapping({"/selectlist"})
    public ResponseResult<List<JSONObject>> list() {
        //查询所有的行为分析任务
        return ResponseResult.ok(ayBehaviorTaskService.selectAyBehaviorList());
    }


    @OpLog(msg = "根据ID查询事件", opType = OpTypeEnum.SELECT)
    @ApiOperation("根据ID查询事件")
    @GetMapping({"/event/{parentId}"})
    public ResponseResult<List<AyEventTypeVo>> selectEventByParentId(@PathVariable("parentId") Integer parentId) {
        //调用service层的方法查询事件
        List<AyEventTypeVo> ayEventTypeList = ayBehaviorTaskService.selectEventByParentId(parentId);
        return ResponseResult.ok(ayEventTypeList);
    }
}
